import Emitter from 'src/utils/Emitter'
import {decorate} from 'src/decorators'
import equals from 'src/utils/equals'
import clone from 'src/utils/clone'
import isObject from 'src/utils/isObject'
import bin from './bin'

const INIT = Symbol('INIT')
const emitter = new Emitter()
const initValues = []

const findModuleName = function (state, target) {
  return Object.keys(state).find(name => target === state[name])
}

// 留待升级用
const getAccess = function (tree, target, path = []) {
  if (tree === target) {
    return path
  }
  if (!isObject(tree)) {
    return []
  }
  for (let property in tree) {
    if (tree.hasOwnProperty(property)) {
      const access = getAccess(tree[property], target, [...path, property])
      if (access.length) {
        return access
      }
    }
  }
  return []
}

// 根据target[property]来找，对于响应式（即内部有复杂getter,setter)的数据偶尔会失灵
const persistDecorator = function (target, property, descriptor, mutations) {
  let moduleName
  emitter.on(INIT, function (store) {
    initValues[property] = clone(target[property])
    const storeValue = bin.getItem(property)
    moduleName = findModuleName(store.state, target)
    if (storeValue) {
      store.replaceState({...store.state, [moduleName]: {...target, [property]: storeValue}})
    }
  })

  mutations.forEach(mutation => {
    emitter.on(mutation, store => {
      const initValue = initValues[property]
      const value = store.state[moduleName][property]
      if (equals(initValue, value)) {
        console.warn('removeItem', value)
        bin.removeItem(property)
      } else {
        bin.setItem(property, value)
      }
    })
  })
}

export const persistent = function (...args) {
  return decorate(persistDecorator, args)
}

const storagePlugin = function (store) {
  emitter.emit(INIT, store)
  store.subscribe(mutation => emitter.emit(mutation.type, store))
}
export default storagePlugin
